package com.wuye.weixin.wxPay;

import com.wuye.web.AppConfig;
import com.wuye.weixin.Configuration;
import com.wuye.weixin.QyWeixin;
import com.wuye.weixin.WeixinException;
import com.wuye.weixin.WeixinManager;
import com.wuye.weixin.pay.*;
import com.wuye.weixin.upUtil.GetWxOrderno;
import com.wuye.weixin.upUtil.RequestHandler;
import com.wuye.weixin.upUtil.Sha1Util;
import com.wuye.weixin.util.TenpayUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.security.MessageDigest;
import java.util.SortedMap;
import java.util.TreeMap;

@Component
public class WeiXinService {
    private Log log = LogFactory.getLog(this.getClass());
    @Autowired
    private AppConfig appConfig;


    /**
     * 获取请求预支付id报文
     *
     * @return
     */
    @SuppressWarnings("static-access")
    /*public String getPackage(String fee, String sn, String openId) {

        // 附加数据 原样返回
        String attach = "";
        // 总金额以分为单位，不带小数点
        String totalFee = getMoney(fee);

        // 订单生成的机器 IP
        String spbill_create_ip = "127.0.0.1";
        // 这里notify_url是 支付完成后微信发给该链接信息，可以判断会员是否支付成功，改变订单状态等。
        String trade_type = "JSAPI";
        // 商户号
        String mch_id = Configuration.getPartnerId();
        // 随机字符串
        String nonce_str = getNonceStr();
        // 商品描述根据情况修改
        String body = "物业订餐订单:" + sn;
        UnifiedOrder unifiedOrder = new UnifiedOrder();
        unifiedOrder.setAppid(Configuration.getOAuthAppId());
        unifiedOrder.setMch_id(mch_id);
        unifiedOrder.setNonce_str(nonce_str);
        unifiedOrder.setBody(body);
        unifiedOrder.setOut_trade_no(sn);
        unifiedOrder.setTotal_fee(totalFee);
        unifiedOrder.setSpbill_create_ip(spbill_create_ip);
        unifiedOrder.setNotify_url(notifyurl);
        unifiedOrder.setTrade_type(trade_type);
        unifiedOrder.setOpenid(openId);

        String sign = SignUtil.getSign(unifiedOrder.toMap(), Configuration.getPartnerKey());

        unifiedOrder.setSign(sign);

        try {
            QyWeixin qyWeixin = WeixinManager.getWeixin();
            UnifiedOrderResult result = qyWeixin.payUnifiedOrder(unifiedOrder);
            log.info("获取JS微信预支付ID：" + result.toString());
            String prepay_id = result.getPrepay_id();
            WCPay wxPay = PayUtil.getBrandWCPayRequest(Configuration.getOAuthAppId(), prepay_id, Configuration.getPartnerKey());
            String paySign = wxPay.getPaySign();
            String finaPackage = "{\"appId\":\"" + Configuration.getOAuthAppId() + "\",\"timeStamp\":\"" + wxPay.getTimeStamp()
                    + "\",\"nonceStr\":\"" + nonce_str + "\",\"package\":\""
                    + wxPay.getPackage() + "\",\"signType\" : \"MD5" + "\",\"paySign\":\""
                    + paySign + "\"}";
            System.out.println("V3 jsApi package:" + finaPackage);
            log.info("获取JS微信支付请求参数： V3 jsApipackage:" + finaPackage);
            return finaPackage;
        } catch (WeixinException e) {
            log.error("========微信支付getPackage时出现异常：" + e);
        }
        return null;
    }*/
/*悦动代码*/
    public String getPackage(String fee, String sn, String openId) {
        //微信支付成功后通知地址 必须要求80端口并且地址不能带参数
         String notifyurl = appConfig.getHost()+"/weixin/weixin_notify_url.jspx";
        return Package(fee, sn, openId, Configuration.getPartnerId(), Configuration.getOAuthAppId(), notifyurl, Configuration.getOAuthSecret(), Configuration.getPartnerKey());
    }

    public String Package(String fee, String sn, String openId, String wxPartner, String wxAppId, String url, String wxAppSecret, String wxPartnerKey) {

        // 附加数据 原样返回
        String attach = "";
        // 总金额以分为单位，不带小数点
        String totalFee = getMoney(fee);

        // 订单生成的机器 IP
        String spbill_create_ip = "127.0.0.1";
        // 这里notify_url是 支付完成后微信发给该链接信息，可以判断会员是否支付成功，改变订单状态等。
        String trade_type = "JSAPI";
        // 商户号
        String mch_id = wxPartner;
        // 随机字符串
        String nonce_str = getNonceStr();
        String body = "物业订餐订单:" + sn;
        UnifiedOrder unifiedOrder = new UnifiedOrder();
        unifiedOrder.setAppid(Configuration.getOAuthAppId());
        unifiedOrder.setMch_id(mch_id);
        unifiedOrder.setNonce_str(nonce_str);
        unifiedOrder.setBody(body);
        unifiedOrder.setOut_trade_no(sn);
        unifiedOrder.setTotal_fee(totalFee);
        unifiedOrder.setSpbill_create_ip(spbill_create_ip);
        unifiedOrder.setNotify_url(url);
        unifiedOrder.setTrade_type(trade_type);
        unifiedOrder.setOpenid(openId);

        String sign = SignUtil.getSign(unifiedOrder.toMap(), Configuration.getPartnerKey());
        unifiedOrder.setSign(sign);

        String xml = unifiedOrder.toXML();
        try {
            QyWeixin qyWeixin = WeixinManager.getWeixin();
            UnifiedOrderResult result = qyWeixin.payUnifiedOrder(unifiedOrder);
            log.info("获取JS微信预支付ID：" + result.toString());
            String prepay_id = result.getPrepay_id();
            log.info("获取JS微信预支付ID：" + prepay_id);
//        System.out.println("获取到的预支付ID：" + prepay_id);
            //获取prepay_id后，拼接最后请求支付所需要的package

            SortedMap<String, String> finalpackage = new TreeMap<String, String>();
            String timestamp = Sha1Util.getTimeStamp();
            String packages = "prepay_id=" + prepay_id;
            finalpackage.put("appId", wxAppId);
            finalpackage.put("timeStamp", timestamp);
            finalpackage.put("nonceStr", nonce_str);
            finalpackage.put("package", packages);
            finalpackage.put("signType", "MD5");
            //要签名
            String finalsign = SignUtil.getSign(finalpackage,Configuration.getPartnerKey());

            String finaPackage = "{\"appId\":\"" + wxAppId + "\",\"timeStamp\":\"" + timestamp
                    + "\",\"nonceStr\":\"" + nonce_str + "\",\"package\":\""
                    + packages + "\",\"signType\" : \"MD5" + "\",\"paySign\":\""
                    + finalsign + "\"}";
            System.out.println("V3 jsApi package:" + finaPackage);
            log.info("获取JS微信支付请求参数： V3 jsApipackage:" + finaPackage);
            return finaPackage;
        }catch (WeixinException e) {
            log.error("========微信支付getPackage时出现异常：" + e);
        }
        return null;
    }

    public final static String getMessageDigest(byte[] buffer) {
        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
        try {
            MessageDigest mdTemp = MessageDigest.getInstance("MD5");
            mdTemp.update(buffer);
            byte[] md = mdTemp.digest();
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取随机字符串
     *
     * @return
     */
    public static String getNonceStr() {
        // 随机数
        String currTime = TenpayUtil.getCurrTime();
        // 8位日期
        String strTime = currTime.substring(8, currTime.length());
        // 四位随机数
        String strRandom = TenpayUtil.buildRandom(4) + "";
        // 10位序列号,可以自行调整。
        return strTime + strRandom;
    }

    /**
     * 元转换成分
     *
     * @param amount
     * @return
     */
    public static String getMoney(String amount) {
        if (amount == null) {
            return "";
        }
        // 金额转化为分为单位
        String currency = amount.replaceAll("\\$|\\￥|\\,", "");  //处理包含, ￥ 或者$的金额
        int index = currency.indexOf(".");
        int length = currency.length();
        Long amLong = 0l;
        if (index == -1) {
            amLong = Long.valueOf(currency + "00");
        } else if (length - index >= 3) {
            amLong = Long.valueOf((currency.substring(0, index + 3)).replace(".", ""));
        } else if (length - index == 2) {
            amLong = Long.valueOf((currency.substring(0, index + 2)).replace(".", "") + 0);
        } else {
            amLong = Long.valueOf((currency.substring(0, index + 1)).replace(".", "") + "00");
        }
        return amLong.toString();
    }
}
